//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "pv.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

PV::PV(GLdouble x, GLdouble y,GLdouble z, bool v){

        this->x=x;
        this->y=y;
        this->z=z;
        this->esVector=v;


}
PV* PV::copiar(){
        return new PV(this->x,this->y,this->z,this->esVector);

}

bool PV::igual(PV * p){
  if((this->x==p->getX()) && (this->y==p->getY())&& (this->esVector==p->getV()))
    return true;
  return false;

}
void PV::vectorDosPV(PV *p1, PV *p2){
        this->x=p2->x-p1->x;
        this->y=p2->y-p1->y;
        this->z=p2->z-p1->z;

}

PV* PV::suma2(PV *v1, PV *v2){
    PV *v=new PV(0,0,0,1);
    v->setX(v1->getX()+v2->getX());
    v->setY(v1->getY()+v2->getY());
    v->setZ(v1->getZ()+v2->getZ());
    return v;


}
void PV::suma(PV *v1, PV *v2){
    this->setX(v1->getX()+v2->getX());
    this->setY(v1->getY()+v2->getY());
    this->setZ(v1->getZ()+v2->getZ());

}
PV *PV::resta(PV* v1, PV* v2){
    PV *v=new PV(0,0,0,0);
    v->setX(v1->getX()-v2->getX());
    v->setY(v1->getY()-v2->getY());
    v->setZ(v1->getZ()-v2->getZ());
    return v;

}
void PV::escalacion(GLdouble a){

    this->setX(this->getX()*a);
    this->setY(this->getY()*a);
    this->setZ(this->getZ()*a);


}
PV* PV::normalizacion(){
    GLdouble m=0;
    m = modulo();
    if (m!=0){
        this->setX((x/m));
        this->setY((y/m));
        this->setZ((z/m));
    }
    
    return this;
}
GLdouble PV::prodEscalar(PV *v1, PV *v2){
        return v1->getX()*v2->getX()+v1->getY()*v2->getY()+v1->getZ()*v2->getZ();
}


GLdouble PV::modulo(){
        return sqrt( pow(x,2) + pow(y,2) + pow(z,2) );

}

//calculo del producto vectorial segun http://es.wikipedia.org/wiki/Producto_vectorial
//sentido:regla del sacacorchos
PV* PV::producto_vectorial(PV * v1,PV *v2){
      PV * v = new PV();
      v->setX( v1->getY() * v2->getZ() - v1->getZ() * v2->getY() );
      v->setY(-v1->getX() * v2->getZ() + v1->getZ() * v2->getX() );
      v->setZ( v1->getX() * v2->getY() - v1->getY() * v2->getX() );
      return v;
}
GLdouble PV::angulo(PV *v1, PV *v2){
      double   denominador = (v1->modulo()*v2->modulo());
      double   numerador = prodEscalar(v1,v2);
      if (denominador == 0)
        return 0;
      if (numerador ==0)
        return 0;
      double parametro = numerador / denominador;
      if (parametro <= -1)
        return M_PI;
       return acos(parametro);//numerador/denominador);

}

